import { ConfigEnv, defineConfig, loadEnv, UserConfigExport } from 'vite';
import vue from '@vitejs/plugin-vue';
import vueJsx from '@vitejs/plugin-vue-jsx';
import { viteExternalsPlugin } from 'vite-plugin-externals';
import path from 'path';
import setting from './src/setting';

// 全局对象
const globalVaries = {
  vue: 'Vue',
  vuex: 'Vuex',
  'vue-router': 'VueRouter',
  'element-plus': 'ElementPlus'
}
const globals = viteExternalsPlugin(globalVaries)

// https://vitejs.dev/config/
export default ({ command, mode }: ConfigEnv): UserConfigExport => {
  const resolve = (dir: string) => {
    return path.join(__dirname, dir);
  }
  const getDateTime = () => {
    let d, s;
    d = new Date();
    s = d.getFullYear(); // 取年份
    s += '' + ('0' + (d.getMonth() + 1)).substr(-2);// 取月份
    s += '' + ('0' + d.getDate()).substr(-2); // 取日期
    s += '' + ('0' + d.getHours()).substr(-2); // 取小时
    s += '' + ('0' + d.getMinutes()).substr(-2); // 取分
    return s;
  }  
  const root = process.cwd()
  const env = loadEnv(mode, root);
  env.VUE_APP_VERSION = require('./package.json').version + '_' + getDateTime();
  const isBuild = command === 'build';
  let plugins = isBuild ? [] : [globals];
  return defineConfig({
    root, // 项目根目录（index.html 文件所在的位置）
    base: './', // 开发或生产环境服务的 公共基础路径
    mode, //  serve 时默认 'development'，build 时默认 'production'
    plugins: [
      vue(),
      vueJsx(),
      ...plugins
    ],
    publicDir: 'public', //作为静态资源服务的文件夹
    resolve: {
      //路径别名
      alias: {
        '@': resolve('src'),
        comps: resolve('src/components'),
        apis: resolve('src/apis'),
        views: resolve('src/views'),
        store: resolve('src/store'),
        routes: resolve('src/routes'),
        styles: resolve('src/styles')
      },
      mainFields: ['module', 'jsnext:main', 'jsnext'], //package.json 中，在解析包的入口点时尝试的字段列表
      extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json'] // 导入时想要省略的扩展名列表
    },
    css: {
      //指定传递给 CSS 预处理器的选项
      preprocessorOptions: {
        scss: {
          //添加 全局变量
          additionalData: '@use "@/styles/global.scss" as *;'
        }
      }
    },
    json: {
      namedExports: true, // 是否支持从 .json 文件中进行按名导入
      stringify: false // 若设置为 true，导入的 JSON 会被转换为 export default JSON.parse("...") 会比转译成对象字面量性能更好，尤其是当 JSON 文件较大的时候。
    },
  
    logLevel: 'info', // 调整控制台输出的级别
  
    clearScreen: true, // 设为 false 可以避免 Vite 清屏而错过在终端中打印某些关键信息
  
    server: {
      //服务器主机名
      host: '0.0.0.0',
      //端口号
      port: 9527,
      //设为 true 时若端口已被占用则会直接退出，而不是尝试下一个可用端口
      strictPort: false,
      //服务器启动时自动在浏览器中打开应用程序,当此值为字符串时，会被用作 URL 的路径名
      open: true,
      //自定义代理规则
      proxy: {
        // 选项写法
        '/basic-api': {
          target: setting.target,
          changeOrigin: true,
          rewrite: (path) => path.replace(/^\/basic-api/, '/manager')
        }
      }
    },
    build: {
      // target: 'es2015', //构建的浏览器兼容目标
      outDir: 'dist', //输出路径
      assetsDir: 'assets', //指定生成静态资源的存放路径
      assetsInlineLimit: 4096, // 4kb 小于此阈值的导入或引用资源将内联为 base64 编码，以避免额外的 http 请求
      cssCodeSplit: true, //启用/禁用 CSS 代码拆分,禁用，整个项目中的所有 CSS 将被提取到一个 CSS 文件中
      sourcemap: false, //构建后是否生成 source map 文件
      lib: {
        entry: resolve('src/components/dialog'), // 设置入口文件
        name: 'dialog', // 起个名字，安装、引入用
        fileName: 'dialog' // 打包后的文件名
      },
      //自定义底层的 Rollup 打包配置
      rollupOptions: {
        external: ['vue', 'vuex', 'vueRouter'],
        plugins: [
          globals
        ],
        // output: {
        //   // 入口文件名
        //   entryFileNames: 'assets/[name].js',
        //   // 块文件名
        //   chunkFileNames: 'assets/[name]-[hash].js',
        //   // 资源文件名 css 图片等等
        //   assetFileNames: 'assets/[name]-[hash].[ext]',
        // }
      },
      // commonjsOptions:RollupCommonJSOptions, //传递给 @rollup/plugin-commonjs 插件的选项配置。
      // lib:{ entry: string, name?: string, formats?: ('es' | 'cjs' | 'umd' | 'iife')[] },  //暴露全局变量,不打包进到文件，依赖进行外部化
      manifest: false, //后端集成,生成 manifest.json 文件
      minify: 'terser', // 禁用最小化混淆，或是用来指定使用哪种混淆器 ,terser 相对较慢，但大多数情况下构建后的文件体积更小
      // terserOptions:TerserOptions, //传递给 Terser 的更多 minify 选项。
      terserOptions: {
        compress: {
          //生产环境时移除console
          drop_console: true,
          drop_debugger: true
        }
      },
      write: true, //常用于 编程式地调用 build() 在写入磁盘之前，需要对构建后的文件进行进一步处理。
      emptyOutDir: true, //  若 outDir 在 root 目录下，则为 true
      brotliSize: true, //启用/禁用 brotli 压缩大小报告。压缩大型输出文件可能会很慢，因此禁用该功能可能会提高大型项目的构建性能。
      chunkSizeWarningLimit: 500 //chunk 大小警告的限制（以 kbs 为单位）。
    },
    // 依赖优化选项 - 依赖预构建
    optimizeDeps: {
      // include: ['vue'] // 默认情况下，不在 node_modules 中的，链接的包不会被预构建。使用此选项可强制预构建链接的包。
      // include: ['element-plus/lib/locale/lang/zh-cn']
    }
  })
}
